from typing import Union
import json
from fastapi import FastAPI
import numpy as np 
from collections import Counter
import pandas as pd

#CORS 跨域
from fastapi.middleware.cors import CORSMiddleware


app = FastAPI()
# 允许跨域
origins = [
    "*",
]
# 允许跨域
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

def softmax(x):
    return np.exp(x) / np.sum(np.exp(x), axis=0)
# 写一个划分训练和测试集的函数
def split_data(data, target, test_size=0.2, random_state=0):
    # 1. 随机打乱数据
    data = data.sample(frac=1, random_state=random_state).reset_index(drop=True)
    # 2. 计算训练集的数量
    train_size = int(len(data) * (1 - test_size))
    # 3. 划分训练集和测试集
    train_data = data[:train_size]
    train_target = target[:train_size]
    test_data = data[train_size:]
    test_target = target[train_size:]
    return train_data, train_target, test_data, test_target
class Solution:
    def __init__(self):
        self.data = pd.read_excel('data.xlsx')
        self.data = self.data.fillna(self.data.mode().iloc[0])
        # 过滤掉提交搭建时间小于15秒的数据
        self.data = self.data[self.data['所用时间'].apply(lambda x: int(x[:len(x)-1])) > 15]
        # 39.144.21.171(河南-新乡) 提取出省份
        self.data['来自IP'] =  self.data['来自IP'].apply(lambda x: x.split('(')[1].split(')')[0].split('-')[0])
        # 将feature_cols 转化为onehot编码
        for col in self.data.columns:
            if self.data[col].dtypes == 'int64':
                self.data[col] = self.data[col].astype('str')
        pass
    def dim1(self):
        # 特征提取
        feature_cols = self.data.iloc[:, 5:11]
        feature_cols = pd.concat([feature_cols, self.data.iloc[:,16],self.data.iloc[:,20]], axis=1)
        taget_cols = self.data.iloc[:,11:13]
        # 两列中（1,1) 映射为1 表示积极的正向作用，(1,0) 映射为2 弱正向，(0,1) 映射为弱逆向，(0,0) 映射为逆向
        mapping = {(1,1):1, (1,2):2, (2,1):3, (2,2):4}
        target = taget_cols.apply(lambda x: mapping[(int(x[0]), int(x[1]))], axis=1)
        origin_data = pd.concat([feature_cols,target],axis=1).values.tolist()
        print(len(origin_data),len(origin_data[0]))
        _origin_label = feature_cols.columns.to_list()+ ['分类']
        origin_label = []
        print(len(_origin_label),len(feature_cols.columns))
        for i in range(len(origin_data[0])):
            if i == 0:
                origin_label.append({'dim':i,'name':'来自IP','type':'category'})
            else:
                origin_label.append({'dim':i,'name':_origin_label[i]})
        province = feature_cols['来自IP'].to_list()
        # 在省份后面补全省的名称，直辖市，特别行政区，自治区
        # 直辖市 北京市 天津市 上海市 重庆市，
        # 自治区 新疆维吾尔自治区 西藏自治区 内蒙古自治区 广西壮族自治区 宁夏回族自治区
        # 特别行政区 香港特别行政区 澳门特别行政区
        city = ['北京市','天津市','上海市','重庆市','新疆维吾尔自治区','西藏自治区','内蒙古自治区','广西壮族自治区','宁夏回族自治区','香港特别行政区','澳门特别行政区']
        for i in range(len(province)):
            f = 0
            for j in city:
                if province[i] in j:
                    f = 1 
                    province[i] = j
                    break
            if f == 0:
                province[i] = province[i] + '省'
        province = Counter(province)
        o = []
        for key,val in province.items():
            o.append({'name':key,'value':val})

        feature_cols = pd.get_dummies(feature_cols)
        data_size = feature_cols.shape
        X_train, y_train, X_test, y_test = split_data(feature_cols, target, test_size=0.2, random_state=0)
        from sklearn.ensemble import RandomForestClassifier
        rf = RandomForestClassifier(n_estimators=100, random_state=0)
        rf.fit(X_train, y_train)
        importance =[i for i in rf.feature_importances_]
        label = feature_cols.columns.to_list()
        return {'label':label,'importance':importance,'data_size':data_size,'province':o,'origin_data':origin_data,'origin_label':origin_label}
    def dim2(self):
        feature_cols = pd.concat([self.data.iloc[:,5:11], self.data.iloc[:,16],self.data.iloc[:,20],self.data.iloc[:,18],self.data.iloc[:,19],self.data.iloc[:,15]], axis=1)
        taget_cols = self.data.iloc[:,11:13]
        mapping = {(1,1):1, (1,2):2, (2,1):3, (2,2):4}
        target = taget_cols.apply(lambda x: mapping[(int(x[0]), int(x[1]))], axis=1)
        target_cols  = self.data.iloc[:,14]
        y = target_cols[target.apply(lambda x:x not in [3, 4])]
        x = feature_cols[target.apply(lambda x:  x not in [3, 4])]
        y2 = self.data.iloc[:,16][target.apply(lambda x:x not in [3, 4])]

        origin_data = pd.concat([x,y],axis=1).values.tolist()
        _origin_label = x.columns.to_list()+ ['分类']
        origin_label = []
        for i in range(len(origin_data[0])):
            if i == 0:
                origin_label.append({'dim':i,'name':'来自IP','type':'category'})
            else:
                origin_label.append({'dim':i,'name':_origin_label[i]})
        province = x['来自IP'].to_list()
        # 在省份后面补全省的名称，直辖市，特别行政区，自治区
        # 直辖市 北京市 天津市 上海市 重庆市，
        # 自治区 新疆维吾尔自治区 西藏自治区 内蒙古自治区 广西壮族自治区 宁夏回族自治区
        # 特别行政区 香港特别行政区 澳门特别行政区
        city = ['北京市','天津市','上海市','重庆市','新疆维吾尔自治区','西藏自治区','内蒙古自治区','广西壮族自治区','宁夏回族自治区','香港特别行政区','澳门特别行政区']
        for i in range(len(province)):
            f = 0
            for j in city:
                if province[i] in j:
                    f = 1 
                    province[i] = j
                    break
            if f == 0:
                province[i] = province[i] + '省'
        province = Counter(province)
        o = []
        for key,val in province.items():
            o.append({'name':key,'value':val})

        x = pd.get_dummies(x)
        data_size = x.shape
        X_train, y_train, X_test, y_test = split_data(x, y2, test_size=0.2, random_state=0)
        from sklearn.ensemble import RandomForestClassifier
        rf = RandomForestClassifier(n_estimators=100, random_state=0)
        rf.fit(X_train, y_train)
        importance =[i for i in rf.feature_importances_]
        label = x.columns.to_list()
        return {'label':label,'importance':importance,'data_size':data_size,'province':o,'origin_data':origin_data,'origin_label':origin_label}
    def dim3(self):
        feature_cols = pd.concat([self.data.iloc[:,5:11], self.data.iloc[:,16],self.data.iloc[:,20],self.data.iloc[:,18],self.data.iloc[:,19],self.data.iloc[:,15]], axis=1)
        taget_cols = self.data.iloc[:,11:13]
        mapping = {(1,1):1, (1,2):2, (2,1):3, (2,2):4}
        target = taget_cols.apply(lambda x: mapping[(int(x[0]), int(x[1]))], axis=1)
        target_cols  = self.data.iloc[:,20]
        y = target_cols[target.apply(lambda x:x not in [3, 4])]
        x = feature_cols[target.apply(lambda x:  x not in [3, 4])]

        origin_data = pd.concat([x,y],axis=1).values.tolist()
        _origin_label = x.columns.to_list()+ ['分类']
        origin_label = []
        for i in range(len(origin_data[0])):
            if i == 0:
                origin_label.append({'dim':i,'name':'来自IP','type':'category'})
            else:
                origin_label.append({'dim':i,'name':_origin_label[i]})
        province = x['来自IP'].to_list()
        # 在省份后面补全省的名称，直辖市，特别行政区，自治区
        # 直辖市 北京市 天津市 上海市 重庆市，
        # 自治区 新疆维吾尔自治区 西藏自治区 内蒙古自治区 广西壮族自治区 宁夏回族自治区
        # 特别行政区 香港特别行政区 澳门特别行政区
        city = ['北京市','天津市','上海市','重庆市','新疆维吾尔自治区','西藏自治区','内蒙古自治区','广西壮族自治区','宁夏回族自治区','香港特别行政区','澳门特别行政区']
        for i in range(len(province)):
            f = 0
            for j in city:
                if province[i] in j:
                    f = 1 
                    province[i] = j
                    break
            if f == 0:
                province[i] = province[i] + '省'
        province = Counter(province)
        o = []
        for key,val in province.items():
            o.append({'name':key,'value':val})

        x = pd.get_dummies(x)
        data_size = x.shape
        X_train, y_train, X_test, y_test = split_data(x, y, test_size=0.2, random_state=0)
        from sklearn.ensemble import RandomForestClassifier
        rf = RandomForestClassifier(n_estimators=100, random_state=0)
        rf.fit(X_train, y_train)
        importance =[i for i in rf.feature_importances_]
        label = x.columns.to_list()
        return {'label':label,'importance':importance,'data_size':data_size,'province':o,'origin_data':origin_data,'origin_label':origin_label}

sol = Solution()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/dim1")
def read_root():
    return sol.dim1()

@app.get("/dim2")
def dim2():
    return sol.dim2()

@app.get("/dim3")
def dim3():
    return sol.dim3()

@app.get("/alcode")
def getalcode():
    with open('./alcode.json','r',encoding='utf-8') as f:
        return json.load(f)

